<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>五子棋</title>
    <link rel="shortcut icon" type="image/x-icon" href="./Black.png"/>
    <style type="text/css">
        .cur {
            margin: 0 0 0 0;
            width: 630px;
            height: 630px;
            float: left;
            border: 1px solid red;
        }

        .btn {
            float: left;
            margin-top: 50px;
            margin-left: 20px;
            width: 100px;
        }

        .btn button {
            width: 100px;
            height: 40px;
            margin-top: 10px;
            border: 2px solid;
            border-radius: 25px;
            -moz-border-radius: 25px;
        }

        #shield { /* 蒙板样式,弹出框后页面不可点击 */
            position: absolute;
            left: 0;
            top: 0;
            background-color: #779bb3;
            width: 100%;
            height: 100%;
            z-index: 250;
            opacity: 0.4;
            filter: alpha(opacity=40);
        }

        #alertFram { /* 弹出框样式 */
            position: absolute;
            width: 280px;
            height: 150px;
            left: 50%;
            top: 50%;
            margin-left: -20px;
            margin-top: -110px;
            text-align: center;
            line-height: 150px;
            z-index: 300;
        }

        #alertFram ul {
            list-style: none;
            margin: 0;
            padding: 0;
            width: 100%;
        }

        #alertFram ul li:nth-child(1) {
            background: #626262;
            text-align: left;
            padding-left: 20px;
            font-size: 14px;
            font-weight: bold;
            height: 25px;
            line-height: 25px;
            border: 1px solid #F9CADE;
            color: white;
        }

        #alertFram ul li:nth-child(2) {
            background: #787878;
            text-align: center;
            font-size: 12px;
            height: 95px;
            line-height: 95px;
            border-left: 1px solid #F9CADE;
            border-right: 1px solid #F9CADE;
            color: #DCC722;
        }

        #alertFram ul li:nth-child(3) {
            background: #626262;
            text-align: center;
            font-weight: bold;
            height: 30px;
            line-height: 25px;
            border: 1px solid #F9CADE;
        }

        #alertFram input {
            width: 80px;
            height: 25px;
            background: #626262;
            color: white;
            border: 1px solid white;
            font-size: 14px;
            line-height: 20px;
            outline: none;
            margin-top: 4px;
        }
    </style>
</head>
<body onload="Draw()">
<div class="cur" id="divCanvas">
    <canvas id="myCanvas" width="630px;" height="630px">
        你的浏览器不支持html5,请使用火狐/谷歌等浏览器
    </canvas>
</div>
<div class="btn">
    <button onclick="window.location.reload();">重新开始</button>
</div>
<script type="text/javascript">
    /* http://blog.csdn.net/lihongxun945/article/category/6089493 */
    window.alert = function (str) { //* 更改系统默认弹窗 */
        var shield = document.createElement("DIV");
        shield.id = "shield";
        var alertFram = document.createElement("DIV");
        alertFram.id = "alertFram";
        alertFram.innerHTML = "<ul><li>[五子棋提示!]</li><li>" + str + "</li><li><input type=\"button\" value=\"确 定\" onclick=\"doOk()\"/></li></ul>";
        document.body.appendChild(alertFram);
        document.body.appendChild(shield);
        this.doOk = function () {
            alertFram.style.display = "none";
            shield.style.display = "none";
        };
        alertFram.focus();
        document.body.onselectstart = function () {
            return false;
        };
    };
    /* 定义变量,以及初始化画布,下面还有电脑的算法,以及判断输赢的代码 */
    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d"); // 注意2d一定是小写
    canvas.addEventListener("click", OnClick, false); //设置鼠标点击函数入口

    var BoardSize = 15; //定义棋盘行列数
    var WinFlag = 0; //* 标记输赢,0表示都没赢,1表示白棋赢,2表示黑棋赢 */
    var Board = new Array(BoardSize * BoardSize); // 标记点位已经落子
    var worker = new Worker('./Gomoku.js'); //* 使用浏览器后台运行五子棋算法,这个必须搭建http服务器,直接打开html文件会报错 */
    var ComputerIsRun = false; //* 标记电脑是否正在思考 */
    var Falg = {empty: 0, hum: 1, com: 2, nor: 0, win: 1};//* 人的角色为1,电脑角色为2,普通棋子为0,胜利棋子为1 */
    /* 下面将图片对象按照,玩家普通子,玩家胜利子,电脑普通子,电脑胜利子,棋盘背景图片 */
    var imgDrawArray = [new Image(), new Image(), new Image(), new Image(), new Image()];
    imgDrawArray[0].src = './White.png';
    imgDrawArray[1].src = './WhiteWin.png';
    imgDrawArray[2].src = './Black.png';
    imgDrawArray[3].src = './BlackWin.png';
    imgDrawArray[4].src = './background.jpg';

    /* 初始化,画棋盘,设置workers回调 */
    function Draw() {
        var i;
        ctx.font = '20px Georgia';
        ctx.drawImage(imgDrawArray[4], 0, 0);
        ctx.fillStyle = '#ff0000';
        for (i = 0; i < BoardSize; i++) {
            ctx.moveTo(0, 25 + 40 * i);//画横线
            ctx.lineTo(650, 25 + 40 * i);
            ctx.fillText((1 + i).toString(), 600, 25 + 40 * i);

            ctx.moveTo(25 + 40 * i, 0);//画纵线
            ctx.lineTo(25 + 40 * i, 650);
            ctx.fillText((1 + i).toString(), 25 + 40 * i, 615);
        }
        ctx.stroke();

        worker.onmessage = function (e) { //* 此处用于处理ai得到结果后返回的数据 */
            var d = e.data; // 得到数据
            if (d.winRole > Falg.empty) { //* 获胜的角色不为空,说明有棋获得胜利 */
                WinFlag = d.winRole; //* 标记胜利的棋子 */
                for (i = d.winPos.length; i--;) {//* 循环画出胜利5个子的位置 */
                    DrawImg(d.winPos[i][0], d.winPos[i][1], WinFlag, Falg.win);
                }
                alert(WinFlag === Falg.hum ? '白棋胜利!' : '黑棋胜利!');
            } else { //* 没有棋胜利则默认,画黑色电脑棋子 */
                DrawImg(d.pos[0], d.pos[1], Falg.com, Falg.nor); //* 画黑色电脑棋子 */
            }

            ComputerIsRun = false;// 标记电脑已经落子
        };
        worker.postMessage({type: 'start', size: BoardSize}); //* 提示ai初始化数据 */
    }

    /* 鼠标点击事件 */
    function OnClick(evt) {
        var QiZi_x = parseInt((evt.layerX - 9) / 40), QiZi_y = parseInt((evt.layerY - 9) / 40);
        if (QiZi_x < 0 || QiZi_y < 0 || QiZi_x >= BoardSize || QiZi_y >= BoardSize || Board[QiZi_x * BoardSize + QiZi_y] > 0) {
            return; //* 点到边缘位置无效,已经落子的位置也无效 */
        }
        if (WinFlag > 0) { //* 如果已经胜利,则无法继续落子! */
            alert((WinFlag === Falg.hum ? '白棋' : '黑棋') + '已经胜利,请重新开始比赛!');
            return;
        }

        if (ComputerIsRun) { //* 如果电脑还在运行则界面无反应 */
            alert('电脑正在思考中...');
        } else {
            ComputerIsRun = true; //* 标记电脑正在运行,此时点击棋盘会提示电脑正在运行的告警 */
            DrawImg(QiZi_x, QiZi_y, Falg.hum, Falg.nor); //* 画白色玩家棋子 */
            worker.postMessage({type: 'go', x: QiZi_x, y: QiZi_y}); //* 向处理线程发送请求 */
        }
    }

    /* 画棋子,X轴下标,Y轴下标,角色(1玩家,2电脑),isWin(0普通棋子,1胜利棋子) */
    function DrawImg(locationX, locationY, role, isWin) {
        Board[locationX * BoardSize + locationY] = role;
        ctx.drawImage(imgDrawArray[(role - 1) * 2 + isWin], 9 + 40 * locationX, 9 + 40 * locationY);
    }
</script>
</body>
</html>
